﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using ERP.Common.DTO;
using ERP.ERPSystem.ProductionSystem.Dto;
using ERP.Team.ProductionSystem;

namespace ERP.ERPSystem.ProductionSystem
{
    /// <summary>
    /// 工序管理应用服务实现类
    /// </summary>
    public class ProcedureServer : ApplicationService, IProcedureServer
    {
        private readonly IRepository<Procedure, int> _procedureRepository;

        /// <summary>
        /// 构造函数，通过依赖注入获取工序仓储的实例
        /// </summary>
        /// <param name="procedureRepository">工序仓储</param>
        public ProcedureServer(IRepository<Procedure, int> procedureRepository)
        {
            _procedureRepository = procedureRepository;
        }

        /// <summary>
        /// 分页查询工序列表，包含筛选和排序功能
        /// </summary>
        public async Task<PagedResult<ProcedureDTO>> GetPagedListAsync(string keyword = null, bool? isEnabled = null, int page = 1, int pageSize = 10)
        {
            // 1. 从仓储获取 IQueryable 对象，用于构建动态查询
            var queryable = await _procedureRepository.GetQueryableAsync();

            // 2. 应用关键词筛选
            if (!string.IsNullOrEmpty(keyword))
            {
                // 筛选条件：工序名称或工序编码包含关键词
                queryable = queryable.Where(c => c.ProcedureName.Contains(keyword) || c.ProcedureCode.Contains(keyword));
            }

            // 3. 应用"是否启用"筛选
            if (isEnabled.HasValue)
            {
                // 将 bool? 转换为实体中的 int? (1=启用, 0=禁用)
                queryable = queryable.Where(c => c.IsNo == (isEnabled.Value ? 1 : 0));
            }
            
            // 4. 获取筛选后的总记录数
            var total = queryable.Count();

            // 5. 应用排序和分页
            var data = queryable
                .OrderByDescending(c => c.Id) // 按ID倒序排序
                .Skip((page - 1) * pageSize)   // 跳过前面页的数据
                .Take(pageSize)                // 获取当前页的数据
                .ToList();                     // 执行查询，返回实体列表

            // 6. 手动将实体列表映射到DTO列表
            var dtoList = data.Select(x => new ProcedureDTO
            {
                Id = x.Id,
                ProcedureCode = x.ProcedureCode,
                ProcedureName = x.ProcedureName,
                IsNo = x.IsNo,
                Context = x.Context
            }).ToList();
            
            // 7. 返回自定义的分页结果对象
            return new PagedResult<ProcedureDTO>
            {
                Total = total,
                Data = dtoList
            };
        }

        /// <summary>
        /// 根据ID获取单个工序的详细信息
        /// </summary>
        public async Task<ProcedureDTO> GetByIdAsync(int id)
        {
            var x = await _procedureRepository.GetAsync(y => y.Id == id);

            if (x == null) return null;
            
            // 手动将实体映射到DTO
            return new ProcedureDTO
            {
                Id = x.Id,
                ProcedureCode = x.ProcedureCode,
                ProcedureName = x.ProcedureName,
                IsNo = x.IsNo,
                Context = x.Context
            };
        }

        /// <summary>
        /// 新增或修改工序。通过检查DTO的Id是否为0来判断是新增还是修改。
        /// </summary>
        public async Task<bool> SaveAsync(ProcedureDTO entity)
        {
            // 如果Id为0，则视为新增操作
            if (entity.Id == 0)
            {
                // 手动创建 Procedure 实体
                var model = new Procedure
                {
                    ProcedureCode = entity.ProcedureCode,
                    ProcedureName = entity.ProcedureName,
                    IsNo = entity.IsNo,
                    Context = entity.Context
                };
                // 插入实体到数据库，并根据返回值判断是否成功
                return await _procedureRepository.InsertAsync(model) != null;
            }
            // 否则，视为修改操作
            else
            {
                // 根据ID从数据库获取现有实体
                var model = await _procedureRepository.GetAsync(entity.Id);
                if (model == null) return false; // 如果实体不存在，返回失败

                // 更新实体的属性
                model.ProcedureCode = entity.ProcedureCode;
                model.ProcedureName = entity.ProcedureName;
                model.IsNo = entity.IsNo;
                model.Context = entity.Context;
                
                // 更新数据库中的实体，并根据返回值判断是否成功
                return await _procedureRepository.UpdateAsync(model) != null;
            }
        }

        /// <summary>
        /// 根据ID删除单个工序
        /// </summary>
        public async Task<bool> DeleteAsync(int id)
        {
            // 根据ID删除实体
            await _procedureRepository.DeleteAsync(x => x.Id == id);
            return true; // 假设操作总是成功
        }

        /// <summary>
        /// 批量删除工序 (注意: 此处为逐条删除，非高效批量操作)
        /// </summary>
        public async Task<bool> DeleteBatchAsync(List<int> ids)
        {
            // 循环遍历ID列表，并逐个删除
            foreach (var id in ids)
            {
                await _procedureRepository.DeleteAsync(x => x.Id == id);
            }
            return true; // 假设操作总是成功
        }
    }
}
